import os
from pathlib import Path
from typing import List
import logging

from setuptools.sandbox import save_path

logging.basicConfig(level=logging.INFO)
def traverse_directory(directory_path: str, show_hidden: bool = False) -> List[str]:
    """
    递归遍历指定目录中的所有文件和子目录

    参数:
        directory_path (str): 要遍历的目录路径
        show_hidden (bool): 是否显示隐藏文件和目录，默认为 False
    """
    results = []
    try:
        # 检查目录是否存在
        if not os.path.exists(directory_path):
            print(f"错误：目录 '{directory_path}' 不存在")
            return

        # 使用 Path 对象处理路径
        path_obj = Path(directory_path)

        # 遍历目录树
        # 递归查找指定模式的文件和目录
        # '*' 是通配符，表示匹配所有文件和目录
        for item in path_obj.rglob('*'):
            # 如果不显示隐藏文件且文件/目录名以 . 开头则跳过
            if not show_hidden and item.name.startswith('.'):
                continue

            # 判断是文件还是目录并打印
            if item.is_file():
                print(f"文件: {item.relative_to(directory_path)}")
                results.append(str(item.relative_to(directory_path).as_posix()))
            elif item.is_dir():
                print(f"目录: {item.relative_to(directory_path)}")
        return results
    except PermissionError:
        print(f"错误：没有权限访问目录 '{directory_path}'")
    except Exception as e:
        print(f"发生未知错误: {e}")


def check_false_alarm(file_path: str, results: list) -> int:
    """
    检查是否存在误报（False Alarm）

    参数:
        file_path (str): 视频文件路径，例如 'fire_videos/neg/negsVideo1.858.avi'
        results (list): 包含报警时间的列表，每个元素是一个字典，包含 'start' 和 'stop' 键

    返回:
        int: 1表示有误报，0表示无误报
    """
    # 检查路径中是否包含 'neg'（负样本，不应报警）
    if '/neg/' in file_path or '\\neg\\' in file_path:
        # 如果 results 不为空，说明有报警，返回1表示误报
        if len(results)!=0:
            logging.info(f"neg 负样本中报警，误报")
            return 1
    return 0


def check_missed_alarm(file_path: str, results: list,total_time: float) -> int:
    """
    检查是否存在漏报（Missed Alarm）

    参数:
        file_path (str): 视频文件路径，例如 'fire_videos/pos/posVideo1.858.avi'
        results (list): 包含报警时间的列表，每个元素是一个字典，包含 'start' 和 'stop' 键

    返回:
        int: 1表示有漏报，0表示无漏报
    """
    # 检查路径中是否包含 'pos'（正样本，应该报警）
    if '/pos/' in file_path or '\\pos\\' in file_path:
        # 如果没有报警结果，认为漏报
        if len(results) == 0:
            logging.info("pos 正样本无报警，漏报")
            return 1

        # 检查首次报警时间是否超过10秒
        if results[0]['start'] > 10:
            logging.info("pos 正样本首次报警超过10s，漏报")
            return 1

        # 检查后续报警间隔是否超过15秒
        for i in range(1, len(results)):
            # 计算当前报警与前一个报警的间隔时间
            interval = results[i]['start'] - results[i - 1]['stop']
            if interval > 15:
                logging.info(f"pos 正样本第{i-1}次到第{i}次报警间隔超过15s，漏报")
                return 1
        # 计算total_time 到 最后一次报警结束的间隔
        interval = total_time - results[-1]['stop']
        if interval > 15:
            logging.info("pos 正样本最后一次报警到结束 间隔超过15s，漏报")
            return 1
    return 0
import cv2
from moviepy import VideoFileClip
os.environ["FFMPEG_BINARY"] = "C:/ffmpeg/ffmpeg-git-full/ffmpeg-2025-05-29-git-75960ac270-full_build/bin/ffmpeg.exe"
def avi_2_mp4(video_path,save_path):
    """
    处理视频文件，使用 YOLO 模型进行目标检测并保存结果
    :param video_path: 输入视频的文件路径
    :param model_path: YOLO 模型的文件路径
    :param save_path: 保存处理后视频的文件路径
    """

    def get_filename(path):
        last_separator_index = path.rfind('/')
        if last_separator_index == -1:
            last_separator_index = path.rfind('\\')
        if last_separator_index != -1:
            filename = path[last_separator_index + 1:]
            print(filename)
            return filename
        else:
            print("未找到有效的路径分隔符，可能提供的就是文件名")
            return path
    # 打开视频文件
    cap = cv2.VideoCapture(video_path)
    clip = VideoFileClip(video_path)
    if not cap.isOpened():
        print('无法打开视频文件')
        return
    audio = clip.audio
    # 获取视频的帧率、宽度和高度
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    # 创建视频写入对象
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    temp_path = os.path.join(".","temp_files",get_filename(video_path))
    if not os.path.exists(os.path.join(".","temp_files")):
        os.mkdir(os.path.join(".","temp_files"))
    print(temp_path)
    if not os.path.exists(os.path.dirname(save_path)):
        print("新建路径:{}".format(os.path.dirname(save_path)))
        os.makedirs(os.path.dirname(save_path))
    save_path_file = os.path.join(os.path.dirname(save_path),os.path.splitext(get_filename(video_path))[0]+".mp4")
    out = cv2.VideoWriter(temp_path, fourcc, fps, (width, height))
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    current_frame = 0
    try:
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
            current_frame += 1
            print(f"正在处理第 {current_frame} 帧，共 {total_frames} 帧")

            # 写入处理后的帧
            out.write(frame)
        # 释放资源
        out.release()
        new_clip = VideoFileClip(temp_path)
        if audio:
            new_clip = new_clip.with_audio(audio)
        new_clip.write_videofile(save_path_file,codec='mpeg4')
        new_clip.close()
    except Exception as e:
        print(e)
    finally:
        clip.close()
        out.release()
        cap.release()
        if audio:
            audio.close()
        # os.remove(temp_path)
def convert_avi_2_mp4():
    target_directory = "E:/迅雷下载/fire_videos"
    save_path = "E:/fire_videos"
    target_directory = "E:/迅雷下载/smoke_videos"
    save_path = "E:/smoke_videos"
    # 调用函数遍历目录
    print(f"正在遍历目录: {os.path.abspath(target_directory)}\n")
    files = traverse_directory(target_directory, show_hidden=False)
    print(files, type(files[0]))
    for file_path in files:
        print(os.path.dirname(os.path.join(save_path,file_path)))
        avi_2_mp4(os.path.join(target_directory,file_path),os.path.dirname(os.path.join(save_path,file_path)))
if __name__ == "__main__":
    # 指定要遍历的目录路径
    target_directory = "./uploads/127.0.0.1-client/"  # 请替换为实际目录路径
    # 调用函数遍历目录
    print(f"正在遍历目录: {os.path.abspath(target_directory)}\n")
    files = traverse_directory(target_directory, show_hidden=False)
    print(files,type(files[0]))

    # print(check_false_alarm(files[0], []),check_false_alarm(files[0], [{"start":0,"stop":1}]))
    # print(check_missed_alarm(files[3], [],20),
    #       check_missed_alarm(files[3], [{"start": 11, "stop": 13}],20),
    #       check_missed_alarm(files[3], [{"start": 1, "stop": 13},{"start": 30, "stop": 40}], 50),
    #       check_missed_alarm(files[3], [{"start": 1, "stop": 13}], 50),
    #       check_missed_alarm(files[3], [{"start": 1, "stop": 13},{"start": 15, "stop": 28}], 40)
    #       )

